<template>
  <div class="container">
    <div 
      id="markdown-input"
      contenteditable="true"
      @input="onInput"
      @paste="onPaste"
      placeholder="在这里输入Markdown...（可直接粘贴图片）">
    </div>

    <div id="preview" v-html="renderedHtml"></div>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const markdownContent = ref('');
const tempImages = ref({});
const renderedHtml = ref('');

// Update preview when content changes
const onInput = () => {
  markdownContent.value = document.getElementById('markdown-input').innerText;
  renderPreviewWithTempImages(markdownContent.value);
};

// Handle pasted images
const onPaste = (e) => {
  const items = e.clipboardData.items;
  console.log("触发图片渲染");
  console.log(items);
  
  for (let item of items) {
    if (item.kind === 'file' && item.type.startsWith('image/')) {
      e.preventDefault();
      const file = item.getAsFile();
      console.log("图片文件为",file);
      // 插入图片
      handleImageInsert(file);
    }
  }

};

// Insert image and handle file reader
const handleImageInsert = (file) => {
  const reader = new FileReader();
  reader.onload = (event) => {
    //base64Url存储的是图片数据
    const base64Url = event.target.result;
    const tempId = `temp-img-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
    const imageSyntax = `![${file.name}](temp://${tempId})\n`;
    // 制造一个暂时链接
    const selection = window.getSelection();

    if (selection.rangeCount > 0) {
      const range = selection.getRangeAt(0);
      console.log("光标位置",range);
      range.deleteContents();
      const textNode = document.createTextNode(imageSyntax);
      range.insertNode(textNode);
      range.setStartAfter(textNode);
      range.setEndAfter(textNode);
      selection.removeAllRanges();
      selection.addRange(range);
    } else {
      markdownContent.value += imageSyntax;
    }

    // Cache temporary image
    tempImages.value[tempId] = { base64: base64Url, filename: file.name, type: file.type };
    
    renderPreviewWithTempImages(markdownContent.value);
  };
  reader.onerror = (error) => {
    console.error('图片处理失败：', error);
    alert(`图片粘贴失败：${error.message || '未知错误'}，请检查图片格式或浏览器权限`);
  };
  // 读取文件数据
  reader.readAsDataURL(file);
};

// Update preview with temporary images
const renderPreviewWithTempImages = (markdown) => {
  let previewHtml = renderMarkdown(markdown);

  Object.keys(tempImages.value).forEach(tempId => {
    const tempUrl = `temp://${tempId}`;
    const base64Url = tempImages.value[tempId].base64;
    previewHtml = previewHtml.replace(new RegExp(escapeRegExp(tempUrl), 'g'), base64Url);
  });

  renderedHtml.value = previewHtml;
};

// Markdown rendering logic (headings, lists, etc.)
const renderMarkdown = (markdown) => {
  let html = handleHeadings(markdown);
  html = handleLine(html);
  html = handleLists(html);
  html = handleInlineElements(html);
  html = handleImages(html);
  html = handleLineBreaks(html);
  return html;

};

// Helper methods (handleHeadings, handleLists, etc.)
const handleHeadings = (markdown) => markdown.replace(/^(#{1,6})\s+(.*?)$/gm, (match, hashes, text) => {
  const level = hashes.length;
  return `<h${level}>${text}</h${level}>`;
});

const handleLists = (markdown) => markdown
  .replace(/^[-*]\s+(.*?)$/gm, '<li>$1</li>')
  .replace(/^(\d+)\.\s+(.*?)$/gm, '<li>$2</li>')
  .replace(/(<li>.*?<\/li>)\s+(?=<li>)/gs, '$1')
  .replace(/^(?!<ul|<ol)(<li>.*?<\/li>)+/gs, '<ul>\n$&\n</ul>')
  .replace(/^(\d+\.\s+.*?)$/gm, (match) => match.includes('<li>') ? match.replace(/<ul>/, '<ol>').replace(/<\/ul>/, '</ol>') : match);

const handleInlineElements = (html) => html
  .replace(/\*\*\*(.*?)\*\*\*/g, '<strong><em>$1</em></strong>')
  .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
  .replace(/\*(.*?)\*/g, '<em>$1</em>')
  .replace(/_(.*?)_/g, '<em>$1</em>')
  .replace(/__(.*?)__/g, '<strong>$1</strong>');
// (/!\[([^\]]*)\]\(([^"\s)]+)(\s+"[^"]*")?\)/g
// 此处正则符号的解析 -> ([^\]*) 捕获组,匹配除了]之外的任意字符,匹配0个或多个字符,

// match 是整个匹配组，之后是不同的捕获组 例如: ![Image](https://example.com/image.png "Title") 
const handleImages = (markdown) => markdown.replace(/!\[([^\]]*)\]\(([^"\s)]+)(\s+"[^"]*")?\)/g, (match, altText, src, title) => {
  const titleAttr = title ? ` title="${title.trim().replace(/^"/, '').replace(/"$/, '')}"` : '';
  console.log("图片匹配结果",match,altText,src,title);
  return `<img src="${src}" alt="${altText}"${titleAttr} style="max-width:100%;height:auto;margin:10px 0;">`;
});

const handleLineBreaks = (html) => html.replace(/([^>])\n/g, '$1<br>\n');
const handleLine = (html) => html.replace(/^\s*[-*_]{3,}\s*(\n|$)/gm, '<hr>');
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

</script>

<style scoped>
.container {
  display: flex;
  gap: 20px;
  padding: 20px;
  height: calc(100vh - 40px);
  box-sizing: border-box;
}

#markdown-input,
#preview {
  flex: 1;
  height: 100%;
  padding: 15px;
  box-sizing: border-box;
  border: 1px solid #ccc;
  border-radius: 4px;
}

#markdown-input {
  font-family: monospace;
  resize: none;
}

#preview h1 {
  color: #2c3e50;
  border-bottom: 1px solid #eee;
}

#preview strong {
  font-weight: bold;
}

#preview em {
  font-style: italic;
  color: #7f8c8d;
}

#preview ul,
#preview ol {
  padding-left: 20px;
  margin: 10px 0;
}

#preview img {
  max-width: 100%;
  height: auto;
  margin: 10px 0;
  border-radius: 4px;
  border: 1px solid #eee;
}
</style>
